#pragma once
#include <d3d9.h>
#include <d3dx9.h>
#include "Vertex4f.h"
#include <vector>

/*  USAGE:
//	VertexCollection vCollection;
//
//	Vertex4f v;
//	v.SetRGBA(1,1,1,1);
//	v.SetXYZW(1,2,1,1);
//	vCollection.AddVertex(v);
//Vertex4f v1;
//	v1.SetRGBA(1,0,1,1);
//	v1.SetXYZW(3,2,1,1);
//	vCollection.AddVertex(v1);
//
//	vCollection.UpdateVertexBufferFromVertices(mDevice);
//	vCollection.UpdateColorBufferFromVertices(mDevice);
//	LPDIRECT3DVERTEXDECLARATION9 vertexDeclaration;
//	mDevice->CreateVertexDeclaration( KVertexCollectionDeclaration, &vertexDeclaration );
//	mDevice->SetVertexDeclaration( vertexDeclaration );
//
//	mDevice->SetStreamSource( 0, vCollection.GetVertexBuffer(), 0, sizeof(Vertex) );
//	mDevice->SetStreamSource( 1, vCollection.GetColorBuffer(),0, sizeof(Color));
*/
static const D3DVERTEXELEMENT9 KVertexCollectionDeclaration[] ={
	//  Stream  Offset         Type                   Method                 Usage          Usage Index       
	{     0,      0,    D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,     0      },
	{     1,      0,    D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,        0      },
	D3DDECL_END()
};

class VertexCollection : public IDXVertBuffer,
						 public IDXColorBuffer
{
	std::vector<Vertex4f> mVertexList;
	LPDIRECT3DVERTEXBUFFER9		mVertexBuffer;
	LPDIRECT3DVERTEXBUFFER9		mColorBuffer;
 public:
	 VertexCollection():mVertexBuffer(NULL), mColorBuffer(NULL){
		
	}
	virtual ~VertexCollection(void){}
	
	HRESULT AddVertex(Vertex4f v) 
	{
		mVertexList.push_back(v);
		return S_OK;
	}

	virtual LPDIRECT3DVERTEXBUFFER9 GetVertexBuffer(){return mVertexBuffer;}
	virtual LPDIRECT3DVERTEXBUFFER9 GetColorBuffer(){return mColorBuffer;}
	virtual HRESULT UpdateVertexBufferFromVertices(CComPtr<IDirect3DDevice9> &mDevice)
	{
		if(mVertexBuffer) mVertexBuffer->Release();

		unsigned int numVerts = mVertexList.size();
		mDevice->CreateVertexBuffer(numVerts * sizeof(Vertex),   
							   0, 0,   
							   D3DPOOL_DEFAULT, &mVertexBuffer, NULL);
		Vertex *pVertices = NULL;
		mVertexBuffer->Lock(0,sizeof(Vertex) * numVerts,(void**)&pVertices,NULL);
		for(unsigned int i = 0; i < numVerts; i++) {
			(pVertices + i)->x = mVertexList[i].GetX();
			(pVertices + i)->y = mVertexList[i].GetY();
			(pVertices + i)->z = mVertexList[i].GetZ();

		}
		mVertexBuffer->Unlock();
		return S_OK;
	
	}
	virtual HRESULT UpdateColorBufferFromVertices(CComPtr<IDirect3DDevice9> &mDevice)
	{
		if(mColorBuffer) mColorBuffer->Release();

		unsigned int numVerts = mVertexList.size();
		mDevice->CreateVertexBuffer(numVerts * sizeof(Color),   
							   0, 0,   
							   D3DPOOL_DEFAULT, &mColorBuffer, NULL);
		Color *pColors = NULL;
		mColorBuffer->Lock(0,sizeof(Color) * numVerts,(void**)&pColors,NULL);
		for(unsigned int i = 0; i < numVerts; i++) {
			(pColors + i)->color = D3DCOLOR_COLORVALUE(
				mVertexList[i].GetR(), 
				mVertexList[i].GetG(), 
				mVertexList[i].GetB(),
				mVertexList[i].GetA());
		}
		mColorBuffer->Unlock();
		return S_OK;
	}
};